package services;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.Query;

import sessions.AdministratorDao;
import sessions.EventDao;
import sessions.MatchDao;
import sessions.PlayerDao;
import sessions.PlayerEventDao;
import sessions.RefereeDao;
import sessions.StaffDao;
import sessions.TeamDao;
import sessions.TournamentDao;
import sessions.UserDao;
import tools.SessionMother;
import entities.Administrator;
import entities.Event;
import entities.Match;
import entities.Player;
import entities.PlayerEvent;
import entities.Referee;
import entities.Staff;
import entities.Team;
import entities.Tournament;
import entities.User;
import enums.Flag;
import enums.MatchStatus;
import enums.TournamentStatus;

@Stateless
public class WebActionBean extends SessionMother implements WebAction {

	@EJB
	private EventDao eventCrud;
	@EJB
	private MatchDao matchCrud;
	@EJB
	private PlayerDao playerCrud;
	@EJB
	private PlayerEventDao playerEventCrud;
	@EJB
	private RefereeDao refereeCrud;
	@EJB
	private StaffDao staffCrud;
	@EJB
	private TeamDao teamCrud;
	@EJB
	private TournamentDao tournamentCrud;
	@EJB
	private UserDao userCrud;
	@EJB
	private AdministratorDao administratorCrud;

	//EVENT
	@Override
	public void createEvent(Event entity) {
		this.eventCrud.create(entity);
	}

	@Override
	public void editEvent(Event entity) {
		this.eventCrud.edit(entity);
	}

	@Override
	public void removeEvent(Event entity) {
		this.eventCrud.remove(entity);
	}

	@Override
	public Event findEvent(Object id) {
		return this.eventCrud.find(id);
	}

	@Override
	public List<Event> findAllEvents() {
		return this.eventCrud.findAll();
	}

	@Override
	public List<Event> findRangeEvents(int[] range) {
		return this.eventCrud.findRange(range);
	}

	@Override
	public int countEvents() {
		return this.eventCrud.count();
	}

	//MATCH

	@Override
	public void createMatch(Match entity) {
		this.matchCrud.create(entity);
	}

	@Override
	public void editMatch(Match entity) {
		this.matchCrud.edit(entity);
	}

	@Override
	public void removeMatch(Match entity) {
		this.matchCrud.remove(entity);
	}

	@Override
	public Match findMatch(Object id) {
		return this.matchCrud.find(id);
	}

	@Override
	public List<Match> findAllMatchs() {
		return this.matchCrud.findAll();
	}

	@Override
	public List<Match> findRangeMatchs(int[] range) {
		return this.matchCrud.findRange(range);
	}

	@Override
	public int countMatchs() {
		return this.matchCrud.count();
	}

	//PLAYER

	@Override
	public void createPlayer(Player entity) {
		this.playerCrud.create(entity);
	}

	@Override
	public void editPlayer(Player entity) {
		this.playerCrud.edit(entity);
	}

	@Override
	public void removePlayer(Player entity) {
		this.playerCrud.remove(entity);
	}

	@Override
	public Player findPlayer(Object id) {
		return this.playerCrud.find(id);
	}

	@Override
	public List<Player> findAllPlayers() {
		return this.playerCrud.findAll();
	}

	@Override
	public List<Player> findRangePlayers(int[] range) {
		return this.playerCrud.findRange(range);
	}

	@Override
	public int countPlayers() {
		return this.playerCrud.count();
	}

	//PLAYEREVENT

	@Override
	public void createPlayerEvent(PlayerEvent entity) {
		this.playerEventCrud.create(entity);
	}

	@Override
	public void editPlayerEvent(PlayerEvent entity) {
		this.playerEventCrud.edit(entity);
	}

	@Override
	public void removePlayerEvent(PlayerEvent entity) {
		this.playerEventCrud.remove(entity);
	}

	@Override
	public PlayerEvent findPlayerEvent(Object id) {
		return this.playerEventCrud.find(id);
	}

	@Override
	public List<PlayerEvent> findAllPlayerEvents() {
		return this.playerEventCrud.findAll();
	}

	@Override
	public List<PlayerEvent> findRangePlayerEvents(int[] range) {
		return this.playerEventCrud.findRange(range);
	}

	@Override
	public int countPlayerEvents() {
		return this.playerEventCrud.count();
	}

	//REFEREE

	@Override
	public void createReferee(Referee entity) {
		this.refereeCrud.create(entity);
	}

	@Override
	public void editReferee(Referee entity) {
		this.refereeCrud.edit(entity);
	}

	@Override
	public void removeReferee(Referee entity) {
		this.refereeCrud.remove(entity);
	}

	@Override
	public Referee findReferee(Object id) {
		return this.refereeCrud.find(id);
	}

	@Override
	public List<Referee> findAllReferees() {
		return this.refereeCrud.findAll();
	}

	@Override
	public List<Referee> findRangeReferees(int[] range) {
		return this.refereeCrud.findRange(range);
	}

	@Override
	public int countReferees() {
		return this.refereeCrud.count();
	}

	//STAFF

	@Override
	public void createStaff(Staff entity) {
		this.staffCrud.create(entity);
	}

	@Override
	public void editStaff(Staff entity) {
		this.staffCrud.edit(entity);
	}

	@Override
	public void removeStaff(Staff entity) {
		this.staffCrud.remove(entity);
	}

	@Override
	public Staff findStaff(Object id) {
		return this.staffCrud.find(id);
	}

	@Override
	public List<Staff> findAllStaffs() {
		return this.staffCrud.findAll();
	}

	@Override
	public List<Staff> findRangeStaffs(int[] range) {
		return this.staffCrud.findRange(range);
	}

	@Override
	public int countStaffs() {
		return this.staffCrud.count();
	}

	//TEAM

	@Override
	public void createTeam(Team entity) {
		this.teamCrud.create(entity);
	}

	@Override
	public void editTeam(Team entity) {
		this.teamCrud.edit(entity);
	}

	@Override
	public void removeTeam(Team entity) {
		this.teamCrud.remove(entity);
	}

	@Override
	public Team findTeam(Object id) {
		return this.teamCrud.find(id);
	}

	@Override
	public List<Team> findAllTeams() {
		return this.teamCrud.findAll();
	}

	@Override
	public List<Team> findRangeTeams(int[] range) {
		return this.teamCrud.findRange(range);
	}

	@Override
	public int countTeams() {
		return this.teamCrud.count();
	}

	//TOURNAMENT

	@Override
	public void createTournament(Tournament entity) {
		this.tournamentCrud.create(entity);
	}

	@Override
	public void editTournament(Tournament entity) {
		this.tournamentCrud.edit(entity);
	}

	@Override
	public void removeTournament(Tournament entity) {
		this.tournamentCrud.remove(entity);
	}

	@Override
	public Tournament findTournament(Object id) {
		Tournament tournament  = this.tournamentCrud.find(id);
		tournament.getListReferees().size();
		tournament.getListTeams().size();
		tournament.getListMatchs().size();
		return tournament;
	}

	@Override
	public List<Tournament> findAllTournaments() {
		return this.tournamentCrud.findAll();
	}

	@Override
	public List<Tournament> findRangeTournaments(int[] range) {
		return this.tournamentCrud.findRange(range);
	}

	@Override
	public int countTournaments() {
		return this.tournamentCrud.count();
	}

	//USER

	@Override
	public void createUser(User entity) {
		this.userCrud.create(entity);
	}

	@Override
	public void editUser(User entity) {
		this.userCrud.edit(entity);
	}

	@Override
	public void removeUser(User entity) {
		this.userCrud.remove(entity);
	}

	@Override
	public User findUser(Object id) {
		return this.userCrud.find(id);
	}

	@Override
	public List<User> findAllUsers() {
		return this.userCrud.findAll();
	}

	@Override
	public List<User> findRangeUsers(int[] range) {
		return this.userCrud.findRange(range);
	}

	@Override
	public int countUsers() {
		return this.userCrud.count();
	}

	//ADMINISTRATOR

	@Override
	public void createAdministrator(Administrator entity) {
		this.administratorCrud.create(entity);
	}

	@Override
	public void editAdministrator(Administrator entity) {
		this.administratorCrud.edit(entity);
	}

	@Override
	public void removeAdministrator(Administrator entity) {
		this.administratorCrud.remove(entity);
	}

	@Override
	public Administrator findAdministrator(Object id) {
		return this.administratorCrud.find(id);
	}

	@Override
	public List<Administrator> findAllAdministrator() {
		return this.administratorCrud.findAll();
	}

	@Override
	public List<Administrator> findRangeAdministrator(int[] range) {
		return this.administratorCrud.findRange(range);
	}

	@Override
	public int countAdministrator() {
		return this.administratorCrud.count();
	}

	// Custom

	@Override
	public List<Tournament> getListTournamentByFlagActivated(){
		try{
			Query query = em.createNamedQuery("getListTournamentByFlagActivated");
			query.setParameter("flag", Flag.activated);

			@SuppressWarnings("unchecked")
			List<Tournament> result = query.getResultList();
			return result;
		}catch(Exception e){
			return new ArrayList<Tournament>();
		}
	}

	@Override
	public List<Team> getListTeamByFlagActivatedByTournament(Tournament oneTournament){
		if(oneTournament != null){
			try{
				Query query = em.createNamedQuery("getListTeamByFlagActivatedByTournament");
				query.setParameter("flag", Flag.activated);
				query.setParameter("tournament", oneTournament);

				@SuppressWarnings("unchecked")
				List<Team> result = query.getResultList();
				return result;
			}catch(Exception e){
				return new ArrayList<Team>();
			}
		}

		return new ArrayList<Team>();
	}

	@Override
	public List<Referee> getListRefereeByFlagActivatedByTournament(Tournament oneTournament){
		if(oneTournament != null){
			try{
				Query query = em.createNamedQuery("getListRefereeByFlagActivatedByTournament");
				query.setParameter("flag", Flag.activated);
				query.setParameter("tournament", oneTournament);

				@SuppressWarnings("unchecked")
				List<Referee> result = query.getResultList();
				return result;
			}catch(Exception e){
				return new ArrayList<Referee>();
			}
		}

		return new ArrayList<Referee>();
	}

	@Override
	public long getCountTeamByTournamentByFlagActivated(Tournament oneTournament){
		if(oneTournament != null){
			try{
				Query query = em.createNamedQuery("getCountTeamByTournamentByFlagActivated");
				query.setParameter("flag", Flag.activated);
				query.setParameter("tournament", oneTournament);

				long result = (long) query.getSingleResult();
				return result;
			}catch(Exception e){
				return 0;
			}
		}

		return 0;
	}

	@Override
	public List<Match> getListMatchByFlagActivatedByTournament(
			Tournament oneTournament) {
		if(oneTournament != null){
			try{
				Query query = em.createNamedQuery("getListMatchByFlagActivatedByTournament");
				query.setParameter("flag", Flag.activated);
				query.setParameter("tournament", oneTournament);

				@SuppressWarnings("unchecked")
				List<Match> result = query.getResultList();
				return result;
			}catch(Exception e){
				return new ArrayList<Match>();
			}
		}

		return new ArrayList<Match>();
	}

	@Override
	public List<Match> getListMatchByFlagActivatedByTournamentAndByStatus(
			Tournament oneTournament, MatchStatus status) {
		if(oneTournament != null){
			try{
				Query query = em.createNamedQuery("getListMatchByFlagActivatedByTournamentAndByStatus");
				query.setParameter("flag", Flag.activated);
				query.setParameter("tournament", oneTournament);
				query.setParameter("status", status);

				@SuppressWarnings("unchecked")
				List<Match> result = query.getResultList();
				return result;
			}catch(Exception e){
				return new ArrayList<Match>();
			}
		}

		return new ArrayList<Match>();
	}
	
	@Override
	public List<Tournament> getListTournamentByFlagActivatedByTournamentStatus(TournamentStatus status){
		if(status != null){
			try{
				Query query = em.createNamedQuery("getListTournamentByFlagActivatedByTournamentStatus");
				query.setParameter("flag", Flag.activated);
				query.setParameter("status", status);

				@SuppressWarnings("unchecked")
				List<Tournament> result = query.getResultList();
				return result;
			}catch(Exception e){
				return new ArrayList<Tournament>();
			}
		}

		return new ArrayList<Tournament>();
	}
	
	public List<Referee> getListRefereeByFlagActivated(){
		try{
			Query query = em.createNamedQuery("getListRefereeByFlagActivated");
			query.setParameter("flag", Flag.activated);

			@SuppressWarnings("unchecked")
			List<Referee> result = query.getResultList();
			
			return result;
		}catch(Exception e){
			return new ArrayList<Referee>();
		}
	}
}